# Copyright (c) 2023 Presto Labs Pte. Ltd.
# Author: dongkwan

import fire
import json
import os
from requests import Session
import json
import time

from collections import defaultdict
from functools import lru_cache

API_KEY = open(os.path.expandvars("$HOME/.cmc_api_key.txt"), "r").readline().rstrip("\n")
HEADERS = {
  "Accepts": "application/json",
  "X-CMC_PRO_API_KEY": API_KEY,
}
SESSION = Session()
SESSION.headers.update(HEADERS)
URL = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest"
EXCEPTIONS = {
  "LUNA2": "LUNA",
  "IOTA": "MIOTA",
  "BCHN": "BCH",
}

@lru_cache
def getInfo(symbol):
  parameters = {"symbol": symbol, "convert": "USD"}
  response = SESSION.get(URL, params=parameters)
  info = json.loads(response.text)
  return info

def _lstrip(string, keyword):
  if string.startswith(keyword):
    return string[len(keyword):]
  return string

def run():
  export_path = os.path.expandvars("$HOME/workspace/coin/data/coin2/quant/cmc_category.json")
  binance_swap_pi_filepath = os.path.expandvars("$HOME/workspace/coin/data/coin2/product_info/Futures.Binance.v1.json")
  native_symbol_map = dict()
  with open(binance_swap_pi_filepath, "r") as fin:
    pi_list = json.load(fin)["product_infos"]
    for single_pi in pi_list:
      native_symbol_map[single_pi["native_symbol"]] = single_pi

  sector_map = defaultdict(set)
  symbols = sorted(set(_lstrip(v["native_base"], "1000") for v in native_symbol_map.values()))
  for symbol in symbols:
    try:
      sectors = getInfo(symbol)["data"][symbol]["tags"]
    except KeyError:
      symbol = EXCEPTIONS.get(symbol)
      sectors = getInfo(symbol)["data"][symbol]["tags"]
    except:
      sectors = None
      print(f"No info for symbol {symbol}")
      continue
    for sector in sectors:
      sector_map[sector].add(symbol)
    time.sleep(2.1) # API call rate limit: 30 requests a minute

  res = {
    "categories": sorted(list(sector_map.keys())),
    "infos": {}
  }
  for k in sorted(sector_map.keys()):
    res["infos"][k] = sorted(sector_map[k])
  with open(export_path, "w") as f:
    json.dump(res, f, indent=2)

  print(sector_map)
  print(f"Dump finished to {export_path}")


if __name__ == "__main__":
  fire.Fire(run)
